package com.unit.util;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;
import org.junit.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class AssertUtil {

	public static void assertMap(Map<String, Object> mapFromCsv, Map<String, Object> mapFromDO) {
		assertMap(mapFromCsv, mapFromDO, null);
	}

	public static void assertMap(Map<String, Object> mapFromCsv, Map<String, Object> mapFromDO,Set<String> skipFieldList) {
		if (skipFieldList == null) {
			skipFieldList = new HashSet<String>();
		}
		Assert.assertNotNull("csv转换对象不能为空", mapFromCsv);
		Assert.assertFalse("csv没有数据", mapFromCsv.isEmpty());
		Assert.assertNotNull("实体转换对象不能为空", mapFromDO);
		for (Map.Entry<String, Object> entry : mapFromCsv.entrySet()) {
			String fieldName = entry.getKey();
			if (skipFieldList.contains(fieldName)) {
				continue;
			}
			Object value = entry.getValue();
			if (value.getClass() == BigDecimal.class) {
				Assert.assertEquals("field=" + fieldName + "; actual=" + value.toString() + "; expect="+ mapFromDO.get(fieldName).toString(),
								new BigDecimal(value.toString()).compareTo(new BigDecimal(mapFromDO.get(fieldName).toString())),
								0);
				
				continue;
			}else if(Calendar.class.isAssignableFrom(value.getClass())) {
				Assert.assertEquals("属性"+fieldName+"的值与csv期望值不一致", JSON.toJSONString(mapFromCsv.get(fieldName),SerializerFeature.WriteDateUseDateFormat), JSON.toJSONString(mapFromDO.get(fieldName),SerializerFeature.WriteDateUseDateFormat));
				continue;
			}else if(LocalDateTime.class.equals(value.getClass())){
				Assert.assertEquals("属性"+fieldName+"的值与csv期望值不一致", JSON.toJSONString(mapFromCsv.get(fieldName),SerializerFeature.WriteDateUseDateFormat), JSON.toJSONString(mapFromDO.get(fieldName),SerializerFeature.WriteDateUseDateFormat));
				continue;
			}
			mapFromDO.put(fieldName, null == mapFromDO.get(fieldName) ? "" : mapFromDO.get(fieldName));
			Assert.assertEquals(fieldName, mapFromCsv.get(fieldName), mapFromDO.get(fieldName));
		}
	}
	
	public static <T> void assertDO(T fromCsv, T fromDO, Set<String> skipFieldList) throws Exception {
		Assert.assertNotNull("csv转换的对象不能为空", fromCsv);
		Assert.assertNotNull("查询实体对象不能为空", fromDO);
		
		Map<String, Class<?>> map = ClassUtil.getFieldClassMap(fromCsv.getClass());
		Set<String> fieldNameList = ClassUtil.getFieldList(fromCsv.getClass());
		for (String field : fieldNameList) {
			if(skipFieldList != null && skipFieldList.contains(field)) {
				continue;
			}
			Class<?> clazz =  map.get(field);
			Object csv = PropertyUtils.getProperty(fromCsv, field);
			Object fdo = PropertyUtils.getProperty(fromDO, field);
			if(Calendar.class.isAssignableFrom(clazz)) {
				Assert.assertEquals("属性"+field+"的值与csv期望值不一致", JSON.toJSONString(csv,SerializerFeature.WriteDateUseDateFormat), JSON.toJSONString(fdo,SerializerFeature.WriteDateUseDateFormat));
			}else if(LocalDateTime.class.equals(clazz)){
				Assert.assertEquals("属性"+field+"的值与csv期望值不一致", JSON.toJSONString(csv,SerializerFeature.WriteDateUseDateFormat), JSON.toJSONString(fdo,SerializerFeature.WriteDateUseDateFormat));
			}else if(String.class.equals(clazz)){
				csv = csv== null?"":csv;
				fdo = fdo==null?"":fdo;
				Assert.assertEquals("属性"+field+"的值与csv期望值不一致", csv, fdo);
			}else if(BigDecimal.class.equals(clazz)){
				Assert.assertEquals("属性"+field+"的值与csv期望值不一致", 0, new BigDecimal(csv.toString()).compareTo(new BigDecimal(fdo.toString())));
			}else {
				Assert.assertEquals("属性"+field+"的值与csv期望值不一致", csv, fdo);
			}
		}
	}
}
